package com.tim.helper.analysis;

import com.tim.util.StringAnalysisUtil;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;

public class SearchConstantInfo {

    @Test
    public void search() throws IOException {
        String dir = "";
        String info = "";
        String[] split = info.trim().split("\\s+");
        Map<String, List<String>> map = readDir(dir);
        for(String str : split){
            String searchStr = "\""+str+"\"";
            StringBuilder builder = new StringBuilder(str);
            for(String key : map.keySet()){
                List<String> fileContents = map.get(key);
                for (int lineNum = 0; lineNum < fileContents.size(); lineNum++) {
                    String line = fileContents.get(lineNum);
                    if(line.contains(searchStr)){
                        StringBuilder preLines = new StringBuilder();
                        int preLineNum = lineNum-1;
                        while(preLineNum>-1){
                            String aLine = fileContents.get(preLineNum--);
                            String trim = (aLine+preLines).trim();
                            if(trim.endsWith("*/")){
                                // 匹配 /**a*/，/*a*/
                                if(trim.startsWith("/*")){
                                    appendComment(key, builder, lineNum, preLines);
                                    break;
                                }
                            }else if(!trim.startsWith("//") && preLines.toString().startsWith("//")){
                                appendComment(key, builder, lineNum, preLines);
                                break;
                            }else if(trim.startsWith("//")){
                                // 匹配多行的//注释
                                if(preLineNum<0){
                                    appendComment(key, builder, lineNum, preLines);
                                    break;
                                }
                            }else if(StringUtils.isNotBlank(trim)){
                                appendComment(key, builder, lineNum, null);
                                break;
                            }
                            preLines.insert(0, aLine.trim());
                        }
                    }
                }
            }
            String builderStr = builder.toString();
            if(builderStr.contains("\t")){
                System.out.println(builder);
            }else{
                System.err.println(builder);
            }
        }
    }

    private static void appendComment(String key, StringBuilder builder, int lineNum, StringBuilder preLines) {
        builder.append("\n\t")
                .append(key.substring(key.lastIndexOf(File.separator)+1))
                .append("-")
                .append(lineNum +1);
        if(preLines!=null){
            builder.append("\t")
                    .append(StringAnalysisUtil.getComment(preLines.toString()));
        }
    }

    private Map<String, List<String>> readDir(String dir) throws IOException {
        String[] suffixs = new String[]{".java",".yml",".properties"};
        Map<String, List<String>> result = new HashMap<>();
        Files.walkFileTree(Paths.get(dir), new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
                String fileFullName = path.toString();
//				System.out.println(fileFullName);
                if(StringUtils.endsWithAny(fileFullName, suffixs)) {
                    try {
                        List<String> contents = Files.readAllLines(path);
                        result.put(fileFullName, contents);
                    }catch (Exception e) {
                        e.printStackTrace();
                        System.out.println(path);
                    }

                }
                return FileVisitResult.CONTINUE;
            }

        });

        return result;
    }
}
